﻿/*
 * @titile: 扫码器
 * @version: 1.0.0
 * @Author: wind
 * @E-Mail: huangchonggao@21cn.com
 * @Date: 2021-10-22 08:11:26
 * @LastEditors: wind
 * @LastEditTime: 2021-10-22 14:09:59
 * @Descripttion: 扫码器工具类 扫二维码 通过USB扫码器接收数据转化序列
 */
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Text;

namespace KFGame
{
    public class KFQRCode : MonoBehaviour
    {
        //启作用
        public bool enter = true;


        public delegate void ReadQRCode(byte[] data);

        public ReadQRCode onQRCards;

        public delegate void BrushMessage(int type, string msg);

        public BrushMessage onBrushMessage;


        //是否允许重复刷卡 false 同一张卡只能刷一次
        public Boolean canRepeat = false;

        // 扫码的长度 来确认码是否有效
        public int codeLength = 16;

        //是否使用前序
        public Boolean usePrefix = false;
        //扫码结构的前缀 确认码是否有效 通过前缀前序区分多个扫码枪 只接收固定的
        public byte prefix = 0xAA;


        public void addListener(ReadQRCode onCode)
        {
            onQRCards += onCode;
        }
        public void removeListener(ReadQRCode onCode)
        {
            onQRCards -= onCode;
        }

        void Start()
        {
            var hander = gameObject.AddComponent<QRCodeHeader>();
            hander.onQRCode = onCodeDatas;
        }

        protected void onCodeDatas(string datas)
        {
            if (datas == null)
                return;

            if (!enter)
            {
                if (onBrushMessage != null)
                    onBrushMessage(4, "未启动刷卡功能");
                return;
            }
            //过虑空格
            datas = datas.Replace(" ", "");

            if (datas.Length < codeLength)
            {
                if (onBrushMessage != null)
                    onBrushMessage(3, "刷卡无效");
                return;
            }

            try
            {
                string sdata = "";
                sdata = datas.Substring(datas.Length - 16);

                byte[] read = strToToHexByte(sdata);

                //启动前序识别                
                if (usePrefix && read[0] != prefix)
                    return;

                //允许重复刷同一张卡
                if (canRepeat)
                {
                    if (onBrushMessage != null)
                        onBrushMessage(1, "刷卡成功");
                    //输出刷卡数据
                    if (onQRCards != null)
                        onQRCards(read);
                }

                //是否己锁卡操作
                if (CardLock(sdata))
                {
                    if (onBrushMessage != null)
                        onBrushMessage(0, "止卡己被使用过");
                    return;
                }

                //锁卡下次不能使用
                lockCard(sdata);

                if (onBrushMessage != null)
                    onBrushMessage(1, "刷卡成功");

                //输出刷卡数据
                if (onQRCards != null)
                    onQRCards(read);


            }
            catch (Exception e)
            {
                if (onBrushMessage != null)
                    onBrushMessage(2, "刷卡处理异常");
                Debug.Log("error " + e.ToString());
            }
        }

        /// <summary>
        /// 当前卡是否被上锁
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public bool CardLock(string name)
        {
            string dirpath = System.IO.Path.Combine(Application.streamingAssetsPath, "QRCode");
            if (!System.IO.Directory.Exists(dirpath))
                System.IO.Directory.CreateDirectory(dirpath);

            string filePath = System.IO.Path.Combine(Application.streamingAssetsPath, "QRCode/" + name);
            return System.IO.File.Exists(filePath);

        }

        /// <summary>
        /// 锁卡操作
        /// </summary>
        /// <param name="name"></param>
        public void lockCard(string name)
        {
            string filePath = System.IO.Path.Combine(Application.streamingAssetsPath, "QRCode/" + name);
            using (System.IO.FileStream stream = System.IO.File.Open(filePath, System.IO.FileMode.OpenOrCreate))
            {
                byte[] str = System.Text.Encoding.Default.GetBytes(name);
                stream.Write(str, 0, str.Length);
                stream.Flush();
                stream.Close();
            }
        }

        /// <summary>
        /// 字符串转16进制字节数组
        /// </summary>
        /// <param name="hexString"></param>
        /// <returns></returns>
        private static byte[] strToToHexByte(string hexString)
        {
            hexString = hexString.Replace(" ", "");
            if ((hexString.Length % 2) != 0)
                hexString += " ";

            byte[] returnBytes = new byte[hexString.Length / 2];
            for (int i = 0; i < returnBytes.Length; i++)
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            return returnBytes;
        }


    }
}